package cn.iocoder.yudao.module.member.service.order;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.util.ipa.MbUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import cn.iocoder.yudao.module.member.controller.admin.siteconfig.vo.SiteConfigurationVo;
import cn.iocoder.yudao.module.member.controller.admin.siteconfig.vo.SysLinkVo;
import cn.iocoder.yudao.module.member.controller.app.order.vo.AppMemberCertificateOrderVo;
import cn.iocoder.yudao.module.member.controller.app.order.vo.HauYangThirdReturnVo;
import cn.iocoder.yudao.module.member.controller.app.order.vo.HauYangThirdVo;
import cn.iocoder.yudao.module.member.controller.app.order.vo.RequestSysVo;
import cn.iocoder.yudao.module.member.dal.dataobject.order.MemberCertificateOrderDo;
import cn.iocoder.yudao.module.member.dal.redis.no.OrderNoRedisDAO;
import cn.iocoder.yudao.module.member.enums.SysFlagEnum;
import cn.iocoder.yudao.module.member.service.siteconfiguration.SiteConfigurationService;
import com.dd.plist.NSDictionary;
import com.dd.plist.PropertyListParser;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.cms.CMSSignedData;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.io.*;
import java.net.SocketException;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;

@Slf4j
@Service
public class HuaYangStrategy implements SysLinkStrategy{

    private final String SITE_CONFIG_CACHE_TOKEN = "SITE:CONFIG:CACHE:TOKEN";
    //B系统调用A系统的接口秒出
    private final String B_To_A = "/api/adddevice";
    //B系统调用A系统的接口预约
    private final String B_TO_A_YY = "/api/addyydevice";

    private final String GETBYID = "/api/Getcertificate";

    private final String SITE_CONFIG_CACHE_MAIN_URL = "SITE:CONFIG:CACHE:MAIN:URL";
    @Resource
    private FileApi fileApi;
    @Resource
    private OrderNoRedisDAO orderNoRedisDAO;
    @Resource
    private SiteConfigurationService siteConfigurationService;
    public static final String DEFAULT_CRT_PASSWORD = "1";




    /**
     * 默认的 csr 内容
     */
    public static final String DEFAULT_CSR_CONTENT = "-----BEGIN CERTIFICATE REQUEST-----\n" +
            "MIIChzCCAW8CAQAwQjELMAkGA1UEBhMCY24xFTATBgNVBAcMDERlZmF1bHQgQ2l0\n" +
            "eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDCCASIwDQYJKoZIhvcNAQEB\n" +
            "BQADggEPADCCAQoCggEBAPHu+Y0sXRRqB19MzxKI3BaWsFGYt8aqhwV2t3ZZUrCL\n" +
            "oXIRd3IblMiOjSYZ7ave/8DVZSBLMC7Wi/xfXxf6GxRVp12mgnaFwVrb+OvW57re\n" +
            "Q8JVuMWkW8EtHxJdBeLdLqMrHHPmk3rsWMmDUJcqZ/iNW7FNeUuA3hAlMjp6gbgN\n" +
            "4KerOryBJAP6KxdVhLB7H63eWbeOn9l3lrVLSnGsPbDP6kGteY9mkkAsl/xP+0iF\n" +
            "AAWuWOZrCMl2yaw0RKp5Mhry5f6kO8IctCbDu9FI/hTkTE9n/rMZdljN04dGusVD\n" +
            "G6GqDs+yQlkp1KXIW6i8L5uxDL3uiqmGJ+VhBxBTaGsCAwEAAaAAMA0GCSqGSIb3\n" +
            "DQEBCwUAA4IBAQCLXxpzeudXRexx4svpgaMiiPxZ+qPeY0f1RZWo/wdSV9TxJ8V/\n" +
            "+SlAHsggKD9pE/EZR4gtq28uWMK01ESOQOz0O3uag5oo8s6+zb2inx+OSUu5tpFT\n" +
            "vkZOPg4JPhBOWc7HqOusyMsb7t0VWw+GE6ofZGnFmVr6FOpvBO2vSErRs+T3P5Ih\n" +
            "306uBMonxeAfGabDYHK5tAMWCVCGH/ZY++YfKkdLV9WCirTun0601SeciXaiYONc\n" +
            "cl7KFQd/1JWoe3TAsYCFECqKR4t1hJtxTLOIxEWLNDn9/n0dBpoT1r4yb4+njusU\n" +
            "cMq81a305kv8ni5FXOWXfg4Vxd0HZ85Z4mA9\n" +
            "-----END CERTIFICATE REQUEST-----";

    /**
     * 默认的私钥内容
     */
    public static final String PRIVATE_KEY_CONTENT = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDx7vmNLF0UagdfTM8SiNwWlrBRmLfGqocFdrd2WVKwi6FyEXdyG5TIjo0mGe2r3v/A1WUgSzAu1ov8X18X+hsUVaddpoJ2hcFa2/jr1ue63kPCVbjFpFvBLR8SXQXi3S6jKxxz5pN67FjJg1CXKmf4jVuxTXlLgN4QJTI6eoG4DeCnqzq8gSQD+isXVYSwex+t3lm3jp/Zd5a1S0pxrD2wz+pBrXmPZpJALJf8T/tIhQAFrljmawjJdsmsNESqeTIa8uX+pDvCHLQmw7vRSP4U5ExPZ/6zGXZYzdOHRrrFQxuhqg7PskJZKdSlyFuovC+bsQy97oqphiflYQcQU2hrAgMBAAECggEASj+OJM5Vrpsvsgavkj+gU+phKFmXJQhWsc2SVmbpYrcnkAtePg3K5pYhKW1RrKqekP6sr3GD0wwTIBvg4knmn6H94FbmuRspkQnrZe2pZocqAm0ubLGZWzrOy2LzGIHK+1aSv9smrdX1FbsQM6RXDkfLuSlOrWZaQFg6Bwpr3yECbQ1fTe0Et4zHCuTZF2xwZCfVXa+zq1flTXReMo8LKvj+nWkWfKSEZZ5OKq9Razs0yuDqYTA2yTQ70wtHj/tfeX282sz/YB98mO+ERO7ZbeknPyKzuMCyVvCALqzixyam8IsK1ifN3aUKhzMrMxjwBKDp6EXEOXJ2NuiQL2NKIQKBgQD5N/Swmy0MTBoPda3j64n/TsPN1hTK9I0aj3OdDGstfc6Gs01wWgfGwDSHzBwgrICrJqV0tT4efbLKdAewqcw2kx5UZQyWzdueR8X/oFERD0MKJGkJL26ZsH4Mjv65WdvB9w2hQD4n3J/DiriNlvbPTk+q8/FZ9NjYEx7au0AJUQKBgQD4hEV/NKiJCrqdvf0pMr2HdiA98KjevsM/r1kjnWuNmJyWc1txQ5ZnRva0PZ/gOm956+6XhEuGztOTZXJVQzgOeMHxcsYJNjNA6X2JBMZotDAuHhceZ2SdTTtCDFcBlaSLtfb4gqdVb/CQW6kfVbl5VMn8wEgZ+H8JauWC8pRm+wKBgQDU3VdxlUk37LSBqekZ+PAIkpUp9gYSiCkRm5+Lb7UHySIi6XlmUm+78iWsK8mGmvDXvw2pjrj9QC37QHnlClLz9lr8iMbk8/X2zqUuvxce9CM1wX25q7rTKO2w+l5VoIvUs5j/tyif0ZDga1dRELXEwcXIZc4rILgqbsJ232NF0QKBgQCLHBd+3i4dEBloJSpp/lIjWpcvtOACV4wZwQDHs925lBzLBuW/4BJ32zxLplcw/+TYvZ1/yPkyC+JZFqdKXOcrCqOdkR6Tl3hXNJwlr7uUbpCtsABG759dghbSoO+vHmHOJtyJPTGH3LIvTG+975Fz/mdWiReTGguabPDuPPWfMwKBgHUJxDu9RXPMQ9KVm4MqpASnjM+Z8M3NUpy8BcjcDJ6tV+1oQ936fAXp5u7G2OvWzEmYj/KRI1OJdg0pKBJ0uO1yoIDMR39wXpOhb6e+YWrKRWXvdhuWOli6c6+9igG+CwqSRYj//Ymv7dKiJH/1ZC3DIth5xutYSJR3SqG0lrUU";
    @Override
    public MemberCertificateOrderDo createOrder(AppMemberCertificateOrderVo appOrderVo) {
        String token = orderNoRedisDAO.getValue(SITE_CONFIG_CACHE_TOKEN);
        String mainUrl = orderNoRedisDAO.getValue(SITE_CONFIG_CACHE_MAIN_URL);
        HauYangThirdVo  hauYangThirdVo = new HauYangThirdVo();
        hauYangThirdVo.setUdid(appOrderVo.getUdid());
        hauYangThirdVo.setType(Integer.parseInt(appOrderVo.getPoolType()));
        //默认全是：0躺平版
        hauYangThirdVo.setWarranty(0);
        String deviceType  = "iphone";
        if ("ipad".equals(appOrderVo.getDeviceType())){
             deviceType  = "ipad";
        }
        MemberCertificateOrderDo  returnDo = BeanUtils.toBean(appOrderVo,MemberCertificateOrderDo.class);
        log.info("调用华阳生成设备信息udid={}设备订单号={}时间={}",appOrderVo.getUdid(),appOrderVo.getCertificateOrderCode(), DateUtil.now()) ;
        StopWatch stopWatch = new StopWatch("调用华阳生成设备信息");
        try {


            HttpResponse execute = null;
            //判断是秒出还是预约
            stopWatch.start("调用华阳生成设备信息开始");
                    if( "0".equals(appOrderVo.getClassType())){

                        try {
                            execute = HttpUtil.createPost(mainUrl + B_To_A+"?"+"udid="+appOrderVo.getUdid()+"&deviceType="+deviceType+"&type="+Integer.parseInt(appOrderVo.getPoolType())+"&warranty="+0+"&token="+token+"&beizhu="+appOrderVo.getUserName())
                                    .header("Content-Type","multipart/form-data").timeout(40000).execute();
                        }catch (cn.hutool.http.HttpException e){
                            if (execute.getStatus() == 504) { // HTTP状态码504表示网关超时
                                System.err.println("请求超时");
                                throw exception(THREAD_ERROR_CODE);
                            } else {
                                System.err.println("HTTP异常: " + e.getMessage());
                            }
                        }
                    }else {

                        try {
                            execute = HttpUtil.createPost(mainUrl + B_TO_A_YY+"?"+"udid="+appOrderVo.getUdid()+"&deviceType="+deviceType+"&type="+Integer.parseInt(appOrderVo.getPoolType())+"&warranty="+0+"&token="+token+"&beizhu="+appOrderVo.getUserName())
                                    .header("Content-Type","multipart/form-data").timeout(40000).execute();
                        }catch (cn.hutool.http.HttpException e){
                            if (execute.getStatus() == 504) { // HTTP状态码504表示网关超时
                                System.err.println("请求超时");
                                throw exception(THREAD_ERROR_CODE);
                            } else {
                                System.err.println("HTTP异常: " + e.getMessage());
                            }
                        }


                    }
            log.info("调用华阳生成设备信息结束");
            stopWatch.stop();
                //秒出
                if (!execute.isOk()){
                    throw exception(MAIN_URL_ERROR);
                }
                String adoResultString = JSONUtil.toJsonStr(execute.body());
                RequestSysVo<HauYangThirdReturnVo> adoResult = JSONUtil.toBean(adoResultString ,RequestSysVo.class);
                if (1 == adoResult.getCode()){
                    log.info("系统创建设备返回日志信息{}",adoResult.getData());
                    HauYangThirdReturnVo hauYangThirdReturnVo = JSONUtil.toBean(JSONUtil.toJsonStr(adoResult.getData()), HauYangThirdReturnVo.class);
                    stopWatch.start("P12转换开始");
                    if (ObjectUtil.isNotEmpty(hauYangThirdReturnVo.getP12())){
                        File tempFileP12 = FileUtil.createTempFile(".p12", false);
                        String fileName = UUID.fastUUID() + "." + FileUtil.getSuffix(tempFileP12);
                        String file =null;
                        try {
                            // 1. Base64解码
                            byte[] p12Bytes = Base64.getDecoder().decode(hauYangThirdReturnVo.getP12().replaceAll("\\s", ""));
                            // 2. 写入文件
                            FileOutputStream fos = new FileOutputStream(tempFileP12);
                            try {
                                fos.write(p12Bytes);
                            }catch (IOException e){
                                log.info("p12文件写入异常{}",e.getMessage());
                                e.printStackTrace();
                            }finally {
                                fos.close();
                            }
                            // 3. 验证证书（可选）
                            KeyStore ks = KeyStore.getInstance("PKCS12");
                            char[] password = "1".toCharArray(); // 如果有密码在此处设置
                            try (InputStream is = FileUtil.getInputStream(Paths.get(tempFileP12.toURI()))) {
                                ks.load(is, password);
                            }
                            System.out.println("证书类型: " + ks.getType());
                            System.out.println("证书别名: " + ks.aliases().nextElement());
                            System.out.println("P12文件生成成功: " + fileName);
                            file =  fileApi.createFile(fileName, "p12", FileUtil.readBytes(tempFileP12));
                            log.info("p12路径"+file);

                            hauYangThirdReturnVo.setP12(file);
                        } catch (Exception e) {
                            log.error("文件转换失败"+e.getMessage());
                            e.printStackTrace();
                        }

                    }
                    stopWatch.stop();
                    stopWatch.start("描述文件转换开始");
                    if (ObjectUtil.isNotEmpty(hauYangThirdReturnVo.getMobileprovision())){
                        File tempFile = FileUtil.createTempFile(".mobileprovision", false);
                        String fileName = UUID.fastUUID() + "." + FileUtil.getSuffix(tempFile);
                        byte[] mpBytes = Base64.getDecoder().decode(hauYangThirdReturnVo.getMobileprovision().replaceAll("\\s", ""));
                        // 2. 写入文件
                        FileOutputStream fosmp = new FileOutputStream(tempFile);
                        try {
                            fosmp.write(mpBytes);
                        }catch (IOException e){
                            log.info("描述文件写入异常{}",e.getMessage());
                            e.printStackTrace();
                        }finally {
                            fosmp.close();
                        }
                        // 解析CMS格式
                        CMSSignedData signedData = new CMSSignedData(mpBytes);
                        byte[] content = (byte[]) signedData.getSignedContent().getContent();

                        // 解析plist内容
                        NSDictionary rootDict = (NSDictionary) PropertyListParser.parse(content);
                        hauYangThirdReturnVo.setTeamName(rootDict.get("TeamName").toString());
                        log.info("描述文件创建成功");
                        String file =  fileApi.createFile(fileName, "mb", FileUtil.readBytes(tempFile));
                        hauYangThirdReturnVo.setMobileprovision(file);
                    }
                    stopWatch.stop();
                    returnDo.setUdid(appOrderVo.getUdid());
                    returnDo.setCerName(hauYangThirdReturnVo.getTeamName());
                    returnDo.setSysIdString(hauYangThirdReturnVo.getId());
                    returnDo.setP12Url(hauYangThirdReturnVo.getP12());
                    returnDo.setMpUrl(hauYangThirdReturnVo.getMobileprovision());
                    returnDo.setDropFlag(Boolean.FALSE) ;
                    returnDo.setP12Password("1");
                    log.info(stopWatch.prettyPrint());
                    return returnDo;
                }else {
                    log.info("系统返回日志信息{}{}",MAIN_URL_EXCEPTION,adoResult.getMsg());
                    throw new RuntimeException(adoResult.getMsg());
                }
            //调用登录接口
        }catch (Exception e){
            log.info("系统返回日志信息{}",e.getMessage());
            throw exception(MAIN_URL_EXCEPTION,e.getMessage());
        }
    }

    @Override
    public String getSysType() {
        return SysFlagEnum.HUA_YANG.getType();
    }

    @Override
    public AppMemberCertificateOrderVo getById(MemberCertificateOrderDo memberCertificateOrderDO) {

        SiteConfigurationVo config = siteConfigurationService.getConfig();
        SysLinkVo sysLinkVo = config.getSysLinkVos().stream().filter(t -> t.getMainUrl().equals(memberCertificateOrderDO.getMainUrl())).findFirst().orElse(null);
        log.info("对应得配置信息"+JSONUtil.toJsonStr(sysLinkVo));
        String token = null;
        if (sysLinkVo != null) {
            token = sysLinkVo.getToken();
        }else {
            throw exception(MAIN_URL_ERROR);
        }
        String mainUrl = memberCertificateOrderDO.getMainUrl();
        HauYangThirdVo  hauYangThirdVo = new HauYangThirdVo();
        hauYangThirdVo.setId(memberCertificateOrderDO.getSysIdString());
        AppMemberCertificateOrderVo returnVo = new AppMemberCertificateOrderVo();
        StopWatch stopWatch = new StopWatch("调用华阳查询设备信息");
        try {
            stopWatch.start("调用接口");
                HttpResponse execute = HttpUtil.createPost( mainUrl+GETBYID+"?"+"token="+token+"&id="+memberCertificateOrderDO.getSysIdString()+"&udid=").execute();
                if (!execute.isOk()){
                    throw exception(MAIN_URL_ERROR);
                }
            stopWatch.stop();
                String adoResultString = JSONUtil.toJsonStr(execute.body());
                RequestSysVo<HauYangThirdReturnVo> adoResult = JSONUtil.toBean(adoResultString ,RequestSysVo.class);
                if (1 == adoResult.getCode()){
                    log.info("系统创建设备返回日志信息{}",adoResult.getData());
                    HauYangThirdReturnVo hauYangThirdReturnVo = JSONUtil.toBean(JSONUtil.toJsonStr(adoResult.getData()), HauYangThirdReturnVo.class);
                    stopWatch.start("p12文件写入");
                        if (ObjectUtil.isNotEmpty(hauYangThirdReturnVo.getP12())) {
                            File tempFileP12 = FileUtil.createTempFile(".p12", false);
                            String fileName = UUID.fastUUID() + "." + FileUtil.getSuffix(tempFileP12);
                            String file = null;
                            try {
                                // 1. Base64解码
                                byte[] p12Bytes = Base64.getDecoder().decode(hauYangThirdReturnVo.getP12().replaceAll("\\s", ""));
                                // 2. 写入文件
                                try (FileOutputStream fos = new FileOutputStream(tempFileP12)) {
                                    fos.write(p12Bytes);
                                }
                                // 3. 验证证书（可选）
                                KeyStore ks = KeyStore.getInstance("PKCS12");
                                char[] password = "1".toCharArray(); // 如果有密码在此处设置
                                try (InputStream is = FileUtil.getInputStream(Paths.get(tempFileP12.toURI()))) {
                                    ks.load(is, password);
                                }
                                System.out.println("证书类型: " + ks.getType());
                                System.out.println("证书别名: " + ks.aliases().nextElement());
                                System.out.println("P12文件生成成功: " + fileName);
                                file = fileApi.createFile(fileName, "p12", FileUtil.readBytes(tempFileP12));
                                log.info("p12路径" + file);

                                hauYangThirdReturnVo.setP12(file);
                            } catch (Exception e) {
                                log.error("文件转换失败" + e.getMessage());
                                e.printStackTrace();
                            }
                        }
                        stopWatch.stop();
                    stopWatch.start("描述文件写入");
                    if (ObjectUtil.isNotEmpty(hauYangThirdReturnVo.getMobileprovision())){
                        File tempFile = FileUtil.createTempFile(".mobileprovision", false);
                        byte[] mpBytes = Base64.getDecoder().decode(hauYangThirdReturnVo.getMobileprovision().replaceAll("\\s", ""));
                        // 2. 写入文件
                        try (FileOutputStream fos = new FileOutputStream(tempFile)) {
                            fos.write(mpBytes);
                        }
                        // 解析CMS格式
                        CMSSignedData signedData = new CMSSignedData(mpBytes);
                        byte[] content = (byte[]) signedData.getSignedContent().getContent();

                        // 解析plist内容
                        NSDictionary rootDict = (NSDictionary) PropertyListParser.parse(content);
                        hauYangThirdReturnVo.setTeamName(rootDict.get("TeamName").toString());
                        log.info("描述文件创建成功");
                        String fileName = UUID.fastUUID() + "." + FileUtil.getSuffix(tempFile);
                        String file =  fileApi.createFile(fileName, "mb", FileUtil.readBytes(tempFile));
                        hauYangThirdReturnVo.setMobileprovision(file);
                    }
                    stopWatch.stop();
                    returnVo.setP12Url(hauYangThirdReturnVo.getP12());
                    returnVo.setMpUrl(hauYangThirdReturnVo.getMobileprovision());
                    returnVo.setDropFlag(hauYangThirdReturnVo.getState());
                    returnVo.setCerName(hauYangThirdReturnVo.getTeamName());
                    log.info(stopWatch.prettyPrint());
                    return returnVo;
                }else {
                    log.info("系统返回日志信息{}{}",MAIN_URL_EXCEPTION,adoResult.getMsg());
                    throw new RuntimeException(adoResult.getMsg());
                }
        }catch (Exception e){
            log.info("系统返回日志信息{}",e.getMessage());
            throw exception(MAIN_URL_EXCEPTION,e.getMessage());
        }
    }
}
